package com.zyt.wiki.interceptor;

/*
 拦截器：Spring框架特有的，常用于登录校验，权限校验，请求日志打印
【方法执行顺序】当进入拦截器链中的某个拦截器，并执行preHandle方法后
    1.当preHandle方法返回false时，从当前拦截器往回执行所有拦截器的afterCompletion方法，再退出拦截器链。也就是说，请求不继续往下传了，直接沿着来的链往回跑。
    2.当preHandle方法返回true时，执行下一个拦截器,直到所有拦截器执行完。再运行被拦截的Controller。然后进入拦截器链，运行所有拦截器的postHandle方法,完后从最后一个拦截器往回执行所有拦截器的afterCompletion方法.
*/

import com.alibaba.fastjson.JSONObject;
import com.zyt.wiki.resp.CommonResp;
import com.zyt.wiki.resp.UserLoginResp;
import com.zyt.wiki.util.LoginUserContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 【操作权限校验】 针对增删改交易，admin用户放行，普通用户被拦截，只允许查询
 */
@Component
public class ActionInterceptor implements HandlerInterceptor {

    public static final Logger LOG = LoggerFactory.getLogger(ActionInterceptor.class) ;

    /** 预处理 */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // OPTIONS请求不做校验（前后端分离的架构, 前端会发一个OPTIONS请求先做预检, 对预检请求不做校验）
        if(request.getMethod().toUpperCase().equals("OPTIONS")){
            return true ; // 返回true，请求会继续往后；返回false，则请求中断
        }

        UserLoginResp userLoginResp = LoginUserContext.getUser();
        if("admin".equals(userLoginResp.getLoginName())){
            return true ; // admin用户不进行拦截，可以进行增删改操作
        }

        String path = request.getRequestURL().toString() ;
        LOG.info("增删改操作被拦截，path: {}", path) ;
        // 组装返回报文，按照约定的json格式
        CommonResp commonResp = new CommonResp() ;
        commonResp.setSuccess(false) ;
        commonResp.setMessage("哈哈，操作被拦截了，你就当操作成功了！游客账号暂不开放增删改操作");
        response.setStatus(HttpStatus.OK.value());
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().print(JSONObject.toJSON(commonResp));
        return false ;  // 返回false，则请求中断，不再往后到Controller
    }

}
